/* Copyright (c) 2016-2020 Enfry Ltd. All Rights Reserved.
 * 
 * This software is the confidential and proprietary information of Enfry. 
 * You shall not disclose such Confidential Information
 * and shall use it only in accordance with the terms of the agreements
 * you entered into with Enfry.
 */
package com.enfry.common.util.String;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.sql.Clob;
import java.sql.SQLException;

import com.enfry.common.util.constants.CodeConstants;
import com.enfry.common.util.constants.SignConstants;
import com.enfry.common.util.excepitiom.CoreRuntimeException;
import com.enfry.common.util.validate.Validates;

/**
 * 
 * @Title com.enfry.util.Strings
 * @author Penghu
 * @date 2016年11月10日
 */
public class Strings implements SignConstants, CodeConstants {
	/********************************************************/
	// 以下创建字符串的和获取字符串字节数组方法
	/********************************************************/

	/** 生成UTF-8的字符串 */
	public static String newStringUTF8(byte[] data) {
		return newString(data, _UTF_8_);
	}

	/** 生成指定编码的字符串 */
	public static String newString(byte[] data, String encoding) {
		try {
			return new String(data, encoding);
		} catch (UnsupportedEncodingException e) {
			return null;
		}
	}

	/** 获取UTF8的字节 */
	public static byte[] getBytesUTF8(String s) {
		try {
			return s.getBytes(_UTF_8_);
		} catch (UnsupportedEncodingException e) {
			return null;
		}
	}

	/** 获取GBK的字节 */
	public static byte[] getBytesGBK(String s) {
		try {
			return s.getBytes(_GBK_);
		} catch (UnsupportedEncodingException e) {
			return null;
		}
	}

	/** 获取ISO8859-1的字节 */
	public static byte[] getBytesISO88591(String s) {
		try {
			return s.getBytes(_ISO_8859_1_);
		} catch (UnsupportedEncodingException e) {
			return null;
		}
	}

	/** 转换为字符串，=NULL时为空字符串 */
	public static String toString(Object o) {
		return (o == null) ? "" : String.valueOf(o);
	}

	/** CLOB字段转换为String */
	public static String clobToString(Clob clob) {
		if (Validates.isEmpty(clob))
			return "";
		String reString = "";
		Reader is;
		try {
			is = clob.getCharacterStream();
			BufferedReader br = new BufferedReader(is);
			String s = br.readLine();
			StringBuffer sb = new StringBuffer();
			while (s != null) {// 执行循环将字符串全部取出付值给StringBuffer由StringBuffer转成STRING
				sb.append(s);
				s = br.readLine();
			}
			reString = sb.toString();
			return reString;
		} catch (IOException e) {
			throw new CoreRuntimeException("clobToString is IOException",e);
		} catch (SQLException e) {
			throw new CoreRuntimeException("clobToString is SQLException",e);
		}
	}

	/** 转换为字符串，=NULL时为缺省值 */
	public static String toString(Object o, String dv) {
		return (o == null) ? dv : String.valueOf(o);
	}

	/**
	 * 把字符串，转化成可能的8种基本类型对象和字符串对象，转化失败其不是基本类型返回null
	 * 
	 * @param clazz
	 *            转化的类型
	 * @param s
	 *            字符串
	 * @return 如果转化成功，返回该类型的值，否则返回null;
	 */
	public static Object toObject(Class<?> clazz, String s) {
		if (s == null)
			return null;

		if (clazz == String.class)
			return s;

		s = s.trim();

		try {
			if (clazz == int.class || clazz == Integer.class)
				return Integer.valueOf(s);
			else if (clazz == long.class || clazz == Long.class)
				return Long.valueOf(s);
			else if (clazz == short.class || clazz == Short.class)
				return Short.valueOf(s);
			else if (clazz == char.class || clazz == Character.class)
				return new Character(s.charAt(0));
			else if (clazz == byte.class || clazz == Byte.class)
				return Byte.valueOf(s);
			else if (clazz == float.class || clazz == Float.class)
				return Float.valueOf(s);
			else if (clazz == double.class || clazz == Double.class)
				return Double.valueOf(s);
			else if (clazz == boolean.class || clazz == Boolean.class)
				return Boolean.valueOf(s);
		} catch (Exception e) {
			return null;
		}

		// 非基本类型和字符串不支持
		return null;
	}

	/**
	 * 字符串(unicode)转为UTF-8的字节数组，各语言通用
	 * 
	 * @param str
	 *            字符串unicode双字节
	 * @return 字节数组，单双三四字节转换
	 */
	public static byte[] toUTF8(String str) {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		for (int i = 0; i < str.length(); i++) {
			char c = str.charAt(i);
			if (c <= 0x7F) {// 0-127 单字节 7 bits
				out.write(c);
			} else if (c <= 0x7FF) {// 128-2047 双字节 11 bits
				out.write(0xC0 | ((c >> 6) & 0x1F));
				out.write(0x80 | (c & 0x3F));
			} else if (c <= 0xFFFF) {// 2048-65535 三字节 16 bits
				out.write(0xE0 | ((c >> 12) & 0x0F));
				out.write(0x80 | ((c >> 6) & 0x3F));
				out.write(0x80 | (c & 0x3F));
			} else {// 65535- 四字节 21 bits
				out.write(0xF0 | (c >> 18));
				out.write(0x80 | ((c >> 12) & 0x3F));
				out.write(0x80 | ((c >> 6) & 0x3F));
				out.write(0x80 | (c & 0x3F));
			}
		}

		return out.toByteArray();
	}

	/********************************************************/
	// 以下字符串扩展使用方法
	/********************************************************/

	/** 首字母大写 */
	public static String toUpperFirstChar(String str) {
		if (str == null)
			return null;

		str = str.trim();
		if (str.length() == 0)
			return "";

		return str.substring(0, 1).toUpperCase() + str.substring(1);
	}

	/** 截取索引后面的字符串 */
	public static String indexOfString(String str, String indexOf) {
		if (str == null || indexOf == null || str.indexOf(indexOf) == -1)
			return str;

		int ind = str.indexOf(indexOf);
		return str.substring(ind + indexOf.length());
	}

	/** 从后面截取索引后面的字符串 */
	public static String lastIndexOfString(String str, String indexOf) {
		if (str == null || indexOf == null || str.lastIndexOf(indexOf) == -1)
			return str;

		int ind = str.lastIndexOf(indexOf);
		return str.substring(ind + indexOf.length());
	}

	/** 获取按含unicode的长度 */
	public static int lengthUnicode(String s) {
		if (s == null || s.length() == 0)
			return 0;

		int len = 0;
		for (int i = 0; i < s.length(); i++) {
			if ((int) s.charAt(i) > 127)
				len += 2;
			else
				len += 1;
		}
		return len;
	}

	/** 长度还剩多少字节 */
	public static int lengthUnicodeRemain(String s, int maxLength) {
		return maxLength - lengthUnicode(s);
	}

	/** 获取按127前长度为3，127后长度为5，计算得的长度 */
	public static int lengUnicode35(String s) {
		if (s == null || s.length() == 0)
			return 0;

		int len = 0;
		for (int i = 0; i < s.length(); i++) {
			if ((int) s.charAt(i) > 127)
				len += 5;
			else
				len += 3;
		}
		return len;
	}

	/**
	 * 截取长度，指定汉字长度
	 * 
	 * @param str
	 *            源串
	 * @param len
	 *            汉字长度
	 * @return 截取后字母串，超长用...代替最后一个汉字
	 */
	public static String substringLen(String str, int len) {
		if (Validates.isEmpty(str))
			return "";

		len = len * 5;// 汉字位*5，再计算
		int length = 0;
		int ind = 0;
		for (int i = 0; i < str.length(); i++) {
			if ((int) str.charAt(i) > 127)
				length += 5;// 汉字和字母宋体比例大概是5:3，即3个汉字和5个字母占位相当
			else
				length += 3;

			ind = i + 1;
			if (length >= len)
				break;
		}

		if (ind < str.length())
			str = str.substring(0, ind - 1) + "...";
		else
			str = str.substring(0, ind);

		return str;
	}

	/**
	 * 替换一个序列，默认占位符为%s
	 * 
	 * @param src
	 *            源串 比如 "您已成功注册到%s，用户名：%s，密码：%s，请登录..."
	 * @param replaceList
	 *            替换列表，比如 {"江苏移动","张三","111111"};
	 * @return 替换后的内容，例子的内容则为： "您已成功注册到江苏移动，用户名：张三，密码：111111，请登录..."
	 */
	public static String replaceSequence(String src, String... replaceList) {
		return replaceSequence(src, "%s", replaceList);
	}

	/**
	 * 替换一个序列
	 * 
	 * @param src
	 *            源串 比如 "您已成功注册到%s，用户名：%s，密码：%s，请登录..."
	 * @param placeholder
	 *            占位符号 比如 "%s"
	 * @param replaceArr
	 *            替换列表，比如 {"江苏移动","张三","111111"};
	 * @return 替换后的内容，例子的内容则为： "您已成功注册到江苏移动，用户名：张三，密码：111111，请登录..."
	 */
	public static String replaceSequence(String src, String placeholder,
			String... replaceArr) {
		int replaceLen = replaceArr.length;

		StringBuilder strb = new StringBuilder();
		String[] segmentArr = src.split(placeholder);
		int len = segmentArr.length;
		int i = 0;
		for (; (i < len - 1 && i < replaceLen); i++) {
			String segment = segmentArr[i];
			strb.append(segment).append(replaceArr[i]);
		}

		for (int j = i; j < len; j++) {
			strb.append(segmentArr[j]);
		}

		return strb.toString();
	}

	/**
	 * 忽略大小写验证startsWith
	 * 
	 * @param s
	 *            被验证字符串
	 * @param prefix
	 *            验证字符串
	 * @return boolean =true表示startsWith, 否则=false
	 */
	public static boolean startsWithIgnoreCase(String s, String prefix) {
		if (prefix == null)
			return true;

		if (s == null || s.length() < prefix.length())
			return false;

		return s.toUpperCase().startsWith(prefix.toUpperCase());
	}

	/**
	 * 忽略大小写验证endsWith
	 * 
	 * @param s
	 *            被验证字符串
	 * @param suffix
	 *            验证字符串
	 * @return boolean =true表示endsWith, 否则=false
	 */
	public static boolean endsWithIgnoreCase(String s, String suffix) {
		if (suffix == null)
			return true;

		if (s == null || s.length() < suffix.length())
			return false;

		return s.toUpperCase().endsWith(suffix.toUpperCase());
	}

	/********************************************************/
	// 以下获取字符串的前缀补位方法
	/********************************************************/

	/**
	 * 后置补齐，通过给定初始str,和前置char,得到给定长度的值, 通常用于前补0等
	 * 
	 * @param value
	 *            原值
	 * @param len
	 *            给定长度
	 * @param suffix
	 *            后置char
	 * @return String 得到前补字符的字符串
	 */
	public static String suffixLen(String value, int len, char suffix) {
		String str = "";
		for (int i = 0; i < len; i++) {
			str += suffix;
		}

		value = value + str;
		return value.substring(0, len);
	}

	/**
	 * 前缀补零，得到给定长度的值,补足0
	 * 
	 * @param str
	 *            初始str
	 * @param len
	 *            给定长度
	 * @return String
	 */
	public static String prefixZero(String str, int len) {
		return prefixLen(str, len, '0');
	}

	/**
	 * 前缀补齐，通过给定初始str,和前置char,得到给定长度的值, 通常用于前补0等
	 * 
	 * @param value
	 *            原值
	 * @param len
	 *            给定长度
	 * @param prefix
	 *            前置char
	 * @return String 得到前补字符的字符串
	 */
	public static String prefixLen(String value, int len, char prefix) {
		String str = "";
		for (int i = 0; i < len; i++) {
			str += prefix;
		}

		value = str + value;
		return value.substring(value.length() - len);
	}

	/**
	 * 前缀补齐，得到给定长度的值,补足0
	 * 
	 * @param value
	 *            原值
	 * @param len
	 *            给定长度
	 * @return String 得到前补0的字符串
	 */
	public static String prefixZero(int value, int len) {
		return prefixLen(value, len, '0');
	}

	/**
	 * 前缀补齐，通过给定初始int,和前置char,得到给定长度的值, 通常用于前补0等
	 * 
	 * @param value
	 *            初值
	 * @param len
	 *            给定长度
	 * @param prefix
	 *            前置char
	 * @return String 得到前补字符的字符串
	 */
	public static String prefixLen(int value, int len, char prefix) {
		String str = "";
		for (int i = 0; i < len; i++) {
			str += prefix;
		}

		str = str + value;
		return str.substring(str.length() - len);
	}

	/**
	 * 前缀补齐，得到给定长度的值,补足0
	 * 
	 * @param value
	 *            初值
	 * @param len
	 *            给定长度
	 * @return String 得到前补字符的字符串
	 */
	public static String prefixZero(long value, int len) {
		return prefixLen(value, len, '0');
	}

	/**
	 * 前缀补齐，通过给定初始int,和前置char,得到给定长度的值, 通常用于前补0等
	 * 
	 * @param value
	 *            初值
	 * @param len
	 *            给定长度
	 * @param prefix
	 *            前置char
	 * @return String 得到前补字符的字符串
	 */
	public static String prefixLen(long value, int len, char prefix) {
		String str = "";
		for (int i = 0; i < len; i++) {
			str += prefix;
		}

		str = str + value;
		return str.substring(str.length() - len);
	}

	/**
	 * 获取字符串的整型数字前缀，如12px,122 str等取前数字
	 * 
	 * @param str
	 *            字符串
	 * @return 数字
	 */
	public static int prefixInt(String str) {
		boolean isNon = '-' == str.charAt(0);
		if (isNon) {
			str = str.substring(1);
		}

		StringBuilder strb = new StringBuilder();
		for (int i = 0; i < str.length(); i++) {
			char c = str.charAt(i);
			if (c < '0' || c > '9')
				break;

			strb.append(c);
		}

		if (strb.length() == 0) {
			return 0;
		}

		int num = Integer.parseInt(strb.toString());
		return isNon ? -num : num;
	}

	/**
	 * 获取字符串的浮点型数字前缀，如12.3px,122 str等取前数字
	 * 
	 * @param str
	 *            字符串
	 * @return 数字
	 */
	public static float prefixFloat(String str) {
		boolean isNon = '-' == str.charAt(0);
		if (isNon) {
			str = str.substring(1);
		}

		StringBuilder strb = new StringBuilder();
		for (int i = 0; i < str.length(); i++) {
			char c = str.charAt(i);
			if ((c < '0' || c > '9') && c != '.')
				break;

			strb.append(c);
		}

		if (strb.length() == 0) {
			return 0;
		}

		// 排除第二个点后面的数字
		String prefix = strb.toString();
		int ind = prefix.indexOf(".");
		if (ind != -1) {
			int ind2 = prefix.indexOf(".", ind + 1);
			if (ind2 != -1)
				prefix = prefix.substring(0, ind2);
		}

		// 前面的可能的0，parseFloat会忽略
		float num = Float.parseFloat(prefix);
		return isNon ? -num : num;
	}

	/********************************************************/
	// 以下获取字符串的出现的次数方法
	/********************************************************/

	/** 获取一个字符在字符串出现的次数 */
	public static int getTimes(String src, char c) {
		int times = 0;
		for (int i = 0; i < src.length(); i++) {
			if (c == src.charAt(i))
				times++;
		}

		return times;
	}

	/** 获取一个字符串在另字符串出现的次数 */
	public static int getTimes(String src, String str) {
		int times = 0;
		if (src == null || str == null)
			return times;

		int len = src.length();
		int timelen = str.length();
		if (len < timelen)
			return times;

		while (true) {
			int ind = src.indexOf(str);
			if (ind == -1)
				return times;

			times++;
			src = src.substring(ind + timelen);
		}
	}

	/********************************************************/
	// 以下整理字符串的方法
	/********************************************************/

	/** 去除前后空白，如果字符串=null，则返回指定的缺省值 */
	public static String trim(String s, String defaultValue) {
		return (s == null) ? defaultValue : s.trim();
	}

	/** 删除字符串前面的空白,直到出现内容，支持去除中文空格12288 */
	public static String trimLeft(String s) {
		if (Validates.isEmpty(s))
			return s;

		int len = s.length(), i = 0;
		while ((i < len) && (s.charAt(i) <= _SPACE_ || s.charAt(i) == 12288))
			i++;
		return (i > 0) ? s.substring(i) : s;
	}

	/** 删除字符串后面的空白,直到出现内容 */
	public static String trimRight(String s) {
		if (Validates.isEmpty(s))
			return s;

		int len = s.length(), i = len - 1;
		while ((i > 0) && (s.charAt(i) <= _SPACE_ || s.charAt(i) == 12288))
			i--;
		return (i < len - 1) ? s.substring(0, i + 1) : s;
	}

	/**
	 * 删除前后缀字符串，如果存在的话
	 * 
	 * @param s
	 *            被删除的字符串
	 * @param prefix
	 *            前缀字符串
	 * @param suffix
	 *            后缀字符串
	 * @return 删除后的字符串
	 */
	public static String trim(String s, String prefix, String suffix) {
		if (Validates.isEmpty(s))
			return s;

		if (!Validates.isEmpty(prefix) && s.startsWith(prefix))
			s = s.substring(prefix.length());

		if (!Validates.isEmpty(suffix) && s.endsWith(suffix))
			s = s.substring(0, s.length() - suffix.length());

		return s;
	}

	/**
	 * 删除前缀字符串
	 * 
	 * @param s
	 *            被删除的字符串
	 * @param prefix
	 *            前缀字符串
	 * @return 删除后的字符串
	 */
	public static String trimLeft(String s, String prefix) {
		if (Validates.isEmpty(s) || Validates.isEmpty(prefix))
			return s;

		if (!s.startsWith(prefix))
			return s;

		return s.substring(prefix.length());
	}

	/**
	 * 删除最后的后缀字符串
	 * 
	 * @param s
	 *            被删除的字符串
	 * @param suffix
	 *            后缀字符串
	 * @return 删除后的字符串
	 */
	public static String trimRight(String s, String suffix) {
		if (Validates.isEmpty(s) || Validates.isEmpty(suffix))
			return s;

		if (!s.endsWith(suffix))
			return s;

		return s.substring(0, s.length() - suffix.length());
	}

	/**
	 * 删除最后的后缀字符串
	 * 
	 * @param strb
	 *            被删除的字符串
	 * @param suffix
	 *            后缀字符串
	 * @return 删除后的字符串
	 */
	public static void trimRight(StringBuilder strb, String suffix) {
		if (strb == null || Validates.isEmpty(suffix)
				|| strb.length() < suffix.length())
			return;

		String end = strb.substring(strb.length() - suffix.length());
		if (suffix.equals(end))
			strb.setLength(strb.length() - suffix.length());
	}

	/********************************************************/
	// 以下删除字符中指定的字符方法
	/********************************************************/

	/**
	 * 删除s中出现的所有背包中定义的字符
	 * 
	 * 举例: s = "adddsg"; bag = "ds"; 得到结果是:returnString = "ag";
	 * 
	 * @param s
	 *            原字符串
	 * @param bag
	 *            包字符串
	 * @return 删除s中出现的所有bag定义的字符后的字符串
	 */
	public static String removeBag(String s, String bag) {
		if (Validates.isEmpty(s) || Validates.isEmpty(bag))
			return s;

		// 逐个字符检查,如果该字符不在bag中,则加入
		StringBuilder strb = new StringBuilder();
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (bag.indexOf(c) > -1)
				continue;

			strb.append(c);
		}

		return strb.toString();
	}

	/**
	 * 删除s中所有背包中未定义的字符
	 * 
	 * 举例: s = "adddsg"; bag = "ds"; 得到结果是:returnString = "ddds";
	 * 
	 * @param s
	 *            原字符串
	 * @param bag
	 *            包字符串
	 * @return 删除s中出现的所有bag未定义的字符后的字符串
	 */
	public static String removeBagNot(String s, String bag) {
		if (Validates.isEmpty(s))
			return s;

		if (Validates.isEmpty(bag))
			return "";

		// 逐个字符检查,如果该字符在bag中,则加入
		StringBuilder strb = new StringBuilder();
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (bag.indexOf(c) == -1)
				continue;

			strb.append(c);
		}

		return strb.toString();
	}

	/**
	 * 删除s中所有空白 (包括空格以下(0x00-0x20)之间的所有字符,包括\t,\r,\n,\b等)
	 * 
	 * 举例: s = " a\tb\rc d ";得到结果是:returnString = "abcd";
	 * 
	 * @param s
	 *            原字符串
	 * @return 删除空白之后的字符串
	 */
	public static String removeAllBlank(String s) {
		if (Validates.isEmpty(s))
			return s;

		StringBuilder strb = new StringBuilder();
		for (int i = 0; i < s.length(); i++) {
			if (s.charAt(i) <= _SPACE_)
				continue;

			strb.append(s);
		}

		return strb.toString();
	}

	/**
	 * 删除可能的第一个分隔符左边的所有字符，如com.zhiqim.fadfox，删除后得到zhiqim.fadfox
	 * 
	 * @param s
	 *            字符串
	 * @param separator
	 *            分隔符
	 * @return 删除后的字符串
	 */
	public static String removeLeftByFirst(String s, String separator) {
		if (Validates.isEmptyBlank(s))
			return "";

		s = s.trim();
		int pos = s.indexOf(separator);
		if (pos == -1)
			return s;

		return s.substring(pos + separator.length());
	}

	/**
	 * 删除可能的最后一个分隔符左边的所有字符，如com.zhiqim.fadfox，删除后得到fadfox
	 * 
	 * @param s
	 *            字符串
	 * @param separator
	 *            分隔符
	 * @return 删除后的字符串
	 */
	public static String removeLeftByLast(String s, String separator) {
		if (Validates.isEmptyBlank(s))
			return "";

		s = s.trim();
		int pos = s.lastIndexOf(separator);
		if (pos == -1)
			return s;

		return s.substring(pos + separator.length());
	}

	/**
	 * 删除可能的第一个分隔符右边的所有字符，如com.zhiqim.fadfox，删除后得到com
	 * 
	 * @param s
	 *            字符串
	 * @param separator
	 *            分隔符
	 * @return 删除后的字符串
	 */
	public static String removeRightByFirst(String s, String separator) {
		if (Validates.isEmptyBlank(s))
			return "";

		s = s.trim();
		int pos = s.indexOf(separator);
		if (pos == -1)
			return s;
		else if (pos < 1)
			return "";
		else
			return s.substring(0, pos);
	}

	/**
	 * 删除可能的最后一个分隔符右边的所有字符，如com.zhiqim.fadfox，删除后得到com.zhiqim
	 * 
	 * @param s
	 *            字符串
	 * @param separator
	 *            分隔符
	 * @return 删除后的字符串
	 */
	public static String removeRightByLast(String s, String separator) {
		if (Validates.isEmptyBlank(s))
			return "";

		s = s.trim();
		int pos = s.lastIndexOf(separator);
		if (pos == -1)
			return s;
		else if (pos < 1)
			return "";
		else
			return s.substring(0, pos);
	}

	/**
	 * 删除s中前缀字符串，如果有的话，功能同trimLeft
	 * 
	 * @param s
	 *            被删除的字符串
	 * @param startsWith
	 *            前缀字符串
	 * @return 删除后的字符串
	 */
	public static String removeStartsWith(String s, String startsWith) {
		return trimLeft(s, startsWith);
	}

	/**
	 * 删除s中后缀字符串，如果有的话，功能同trimRight
	 * 
	 * @param s
	 *            被删除的字符串
	 * @param endsWith
	 *            后缀字符串
	 * @return 删除后的字符串
	 */
	public static String removeEndsWith(String s, String endsWith) {
		return trimRight(s, endsWith);
	}

	/**
	 * 删除s中后缀字符串，如果有的话，功能同trimRight
	 * 
	 * @param s
	 *            被删除的字符串
	 * @param endsWith
	 *            后缀字符串
	 * @return 删除后的字符串
	 */
	public static void removeEndsWith(StringBuilder strb, String endsWith) {
		trimRight(strb, endsWith);
	}

	/**
	 * 增加s中前缀字符串，如果需要的话
	 * 
	 * 举例 : 1) s == null, startsWith == null，返回null 2) s == null, startsWith ==
	 * ""，返回"" 3) s != null, startsWith == null || == ""，返回s 4)
	 * s.startsWith(startsWith)，返回s 5) !s.startsWith(startsWith)，返回startsWith +
	 * s
	 * 
	 * @param s
	 *            原字符串
	 * @param startsWith
	 *            前缀字符串
	 * @return 增加后的字符串
	 */
	public static String addStartsWith(String s, String startsWith) {
		if (s == null)
			return startsWith;

		if (Validates.isEmpty(startsWith))
			return s;

		if (s.startsWith(startsWith))
			return s;

		return startsWith + s;
	}

	/**
	 * 增加s中后缀字符串，如果需要的话
	 * 
	 * 举例 : 1) s == null, endsWith == null，返回null 2) s == null, endsWith ==
	 * ""，返回"" 3) s != null, endsWith == null || == ""，返回s 4)
	 * s.endsWith(endsWith)，返回s 5) !s.endsWith(endsWith)，返回s + endsWith
	 * 
	 * @param s
	 *            原字符串
	 * @param endsWith
	 *            前缀字符串
	 * @return 增加后的字符串
	 */
	public static String addEndsWith(String s, String endsWith) {
		if (s == null)
			return endsWith;

		if (Validates.isEmpty(endsWith))
			return s;

		if (s.endsWith(endsWith))
			return s;

		return s + endsWith;
	}

	/**
	 * 增加新行\r\n
	 * 
	 * @param strb
	 *            变长字符串
	 */
	public static StringBuilder addNewLine(StringBuilder strb) {
		return strb.append(_BR_);
	}

	/**
	 * 增加新行\r\n
	 * 
	 * @param strb
	 *            变长字符串
	 */
	public static StringBuffer addNewLine(StringBuffer strb) {
		return strb.append(_BR_);
	}

	/**
	 * 增加多个双空格
	 * 
	 * @param strb
	 *            变长字符串
	 * @param num
	 *            双空格数
	 */
	public static StringBuilder addTwoSpace(StringBuilder strb, int num) {
		for (int i = 0; i < num; i++)
			strb.append(_TWO_);
		return strb;
	}

	/**
	 * 增加多个双空格
	 * 
	 * @param strb
	 *            变长字符串
	 * @param num
	 *            双空格数
	 */
	public static StringBuffer addTwoSpace(StringBuffer strb, int num) {
		for (int i = 0; i < num; i++)
			strb.append(_TWO_);
		return strb;
	}

	/**
	 * 增加多个四空格
	 * 
	 * @param strb
	 *            变长字符串
	 * @param num
	 *            四空格数
	 */
	public static StringBuilder addFourSpace(StringBuilder strb, int num) {
		for (int i = 0; i < num; i++)
			strb.append(_FOUR_);

		return strb;
	}

	/**
	 * 增加多个四空格
	 * 
	 * @param strb
	 *            变长字符串
	 * @param num
	 *            四空格数
	 */
	public static StringBuffer addFourSpace(StringBuffer strb, int num) {
		for (int i = 0; i < num; i++)
			strb.append(_FOUR_);
		return strb;
	}

	/**
	 * 增加多个制表符
	 * 
	 * @param strb
	 *            变长字符串
	 * @param num
	 *            制表符数
	 */
	public static StringBuilder addTab(StringBuilder strb, int num) {
		for (int i = 0; i < num; i++)
			strb.append(_TAB_);

		return strb;
	}

	/**
	 * 增加多个制表符
	 * 
	 * @param strb
	 *            变长字符串
	 * @param num
	 *            制表符数
	 */
	public static StringBuffer addTab(StringBuffer strb, int num) {
		for (int i = 0; i < num; i++)
			strb.append(_TAB_);
		return strb;
	}

	/**
	 * 
	 * 根据字符串字节数截取字符
	 * 
	 * @param str
	 * @param subSLength
	 * @return
	 * @return String
	 * @throws
	 * @author ylf
	 * @date 2017年6月19日
	 */
	public static String subStrByBtLength(String str, int subSLength)
			throws UnsupportedEncodingException {
		if (str == null)
			return "";
		else {
			int tempSubLength = subSLength;// 截取字节数
			String subStr = str.substring(0,
					str.length() < subSLength ? str.length() : subSLength);// 截取的子串
			int subStrByetsL = subStr.getBytes("GBK").length;// 截取子串的字节长度
			// int subStrByetsL = subStr.getBytes().length;//截取子串的字节长度
			// 说明截取的字符串中包含有汉字
			while (subStrByetsL > tempSubLength) {
				int subSLengthTemp = --subSLength;
				subStr = str.substring(0,
						subSLengthTemp > str.length() ? str.length()
								: subSLengthTemp);
				subStrByetsL = subStr.getBytes("GBK").length;
				// subStrByetsL = subStr.getBytes().length;
			}
			return subStr;
		}
	}
}
